/*
 * Copyright 2010 Florian Sauter
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package de.rentoudu.chat.server;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.Transaction;
import com.googlecode.objectify.AsyncObjectify;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.NotFoundException;
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyFactory;
import com.googlecode.objectify.ObjectifyService;
import com.googlecode.objectify.Query;

import de.rentoudu.chat.model.Channel;
import de.rentoudu.chat.model.Message;

/**
 * Kind of an entity manager for objectify.
 * 
 * @author Florian Sauter
 *
 */
public class ObjectifyManager extends com.googlecode.objectify.util.DAOBase implements Objectify {

	public ObjectifyManager() {
		registerEntities();
	}
	
	/**
	 * Entity registrations.
	 */
	protected void registerEntities(){
		ObjectifyService.register(Message.class);
		ObjectifyService.register(Channel.class);
	}
	
	@Override
	public <T> Map<Key<T>, T> get(Iterable<? extends Key<? extends T>> keys) {
		return ofy().get(keys);
	}

	@Override
	public <T> T get(Key<? extends T> key) throws NotFoundException {
		return ofy().get(key);
	}

	@Override
	public <T> T get(Class<? extends T> clazz, long id) throws NotFoundException {
		return ofy().get(clazz, id);
	}

	@Override
	public <T> T get(Class<? extends T> clazz, String name) throws NotFoundException {
		return ofy().get(clazz, name);
	}

	@Override
	public <S, T> Map<S, T> get(Class<? extends T> clazz, Iterable<S> idsOrNames) {
		return ofy().get(clazz, idsOrNames);
	}

	@Override
	public <S, T> Map<S, T> get(Class<? extends T> clazz, S... idsOrNames) {
		return ofy().get(clazz, idsOrNames);
	}

	@Override
	public <T> T find(Key<? extends T> key) {
		return ofy().find(key);
	}

	@Override
	public <T> T find(Class<? extends T> clazz, long id) {
		return ofy().find(clazz, id);
	}

	@Override
	public <T> T find(Class<? extends T> clazz, String name) {
		return ofy().find(clazz, name);
	}

	@Override
	public <T> Key<T> put(T obj) {
		return ofy().put(obj);
	}

	@Override
	public <T> Map<Key<T>, T> put(Iterable<? extends T> objs) {
		return ofy().put(objs);
	}

	@Override
	public <T> Map<Key<T>, T> put(T... objs) {
		return ofy().put(objs);
	}

	@Override
	public void delete(Iterable<?> keysOrEntities) {
		ofy().delete(keysOrEntities);
	}

	@Override
	public <T> void delete(Class<T> clazz, long id) {
		ofy().delete(clazz, id);
	}

	@Override
	public <T> void delete(Class<T> clazz, String name) {
		ofy().delete(clazz, name);
	}

	@Override
	public <T> com.googlecode.objectify.Query<T> query() {
		return ofy().query();
	}

	@Override
	public <T> com.googlecode.objectify.Query<T> query(Class<T> clazz) {
		return ofy().query(clazz);
	}

	public <T> com.googlecode.objectify.Query<T> query(Class<T> clazz, HashMap<String, Object> queryFilters) {
		Query<T> customFilterQuery = ofy().query(clazz);
		appendCustomQueryFilters(customFilterQuery, queryFilters);
		return customFilterQuery;
	}
	
	protected <T> com.googlecode.objectify.Query<T> appendCustomQueryFilters(Query<T> query, HashMap<String, Object> queryFilters){
		Iterator<String> iterator = queryFilters.keySet().iterator();
		while (iterator.hasNext()) {
			String filterKey = iterator.next();
			Object filterValue = queryFilters.get(filterKey);
			query = query.filter(filterKey, filterValue);
		}
		return query;
	}
	
	@Override
	public Transaction getTxn() {
		return ofy().getTxn();
	}

	@Override
	public DatastoreService getDatastore() {
		return ofy().getDatastore();
	}

	@Override
	public ObjectifyFactory getFactory() {
		return ofy().getFactory();
	}

	@Override
	public AsyncObjectify async() {
		return ofy().async();
	}

	@Override
	public void delete(Object... arg0) {
		ofy().delete(arg0);
	}
}